package com.controller;


import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class VariablesController {
	
	@Autowired
	private ProcessEngine processEngine;
	
	/**
	 * 部署
	 * @return
	 */
	@RequestMapping("deploy")
	public String deploy(){
		InputStream bpmn = this.getClass().getResourceAsStream("/diagrams/Variables.bpmn");
		InputStream png = this.getClass().getResourceAsStream("/diagrams/Variables.png");
		
		Deployment deployment = processEngine.getRepositoryService().createDeployment().name("变量流程")
			.addInputStream("Variables.bpmn", bpmn)//与资源文件名称要一致
			.addInputStream("Variables.png", png)
			.deploy();
		
		System.err.println(deployment.getKey() + "---" + deployment.getName());
		
		return deployment.getId();
		
	}
	
	/**
	 * 启动流程实例
	 * @return
	 */
	@RequestMapping("startVar")
	public String startFlow(){
		
		String processDefinitionKey = "ProcessVariable";
		
		//正在执行的流程实例和执行对象相关的service
		RuntimeService runtimeService = processEngine.getRuntimeService();
		
		//使用流程定义的key启动流程实例，key对应的是bpmn文件中的id，默认是最新版本的流程启动
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
		
		System.out.println(processInstance.getId() + processInstance.getProcessDefinitionId());
		
		return processInstance.getProcessDefinitionId();
	}
	
	/**
	 * 设置流程变量
	 * @return
	 */
	@RequestMapping("setVariables")
	public String setVariables(){
		
		TaskService taskService = processEngine.getTaskService();
		
		String taskId ="17502";
		
		//设置
		taskService.setVariable(taskId, "请假天数", 3);

		Map<String, String> map = new HashMap<String, String>();
		map.put("请假原因", "出去玩儿");
		
		taskService.setVariables(taskId, map);
		
		//查询
		List<String> list = new ArrayList<String>();
		list.add("请假原因");
		list.add("请假天数");
		
		Map<String, Object> vMap = taskService.getVariables(taskId,list);
		
		System.err.println(vMap.toString());
		
		return "设置流程变量成功！";
	}
	
	/**
	 * 模拟设置和获取流程变量的场景
	 * @return
	 */
	public String setAndGetVariables(){
		
		//与流程实例，执行对象
		RuntimeService runtimeService = processEngine.getRuntimeService();
		
		//与任务
		TaskService taskService = processEngine.getTaskService();
		
		/*表示使用执行对象ID，和流程变量的名称，设置流程变量的值（一次只能设置一个值）*/
		//runtimeService.setVariable(executionId, variableName, value);
		/*表示执行对象ID，和map集合设置流程变量，map集合的key是流程变量名称，value是变量值*/
		//runtimeService.setVariables(executionId, variables);
		/*表示使用任务ID，和流程变量的名称，设置流程变量的值（一次只能设置一个值）*/
		//taskService.setVariable(taskId, variableName, value);
		/*表示任务ID，和map集合设置流程变量，map集合的key是流程变量名称，value是变量值*/
		//taskService.setVariables(taskId, variables);
		
		//启动流程实例的时候也可以设置流程变量
		//runtimeService.startProcessInstanceById(arg0, arg1)
		//完成任务提交时，也可以设置流程变量
		//taskService.complete(arg0, arg1);
		
		/**
		 * 设置流程变量，还可以用javaBean类型
		 * 但要求JavaBean可序列化，且当JavaBean放入流程变量中，要求JavaBean的属性不能再发生变化
		 * 如果发生变化，再获取的时候，抛出异常；
		 * 也可指定实体的序列化版本id
		 * 
		 * 序列化的值存储在资源文件表
		 */
		
		
		/**
		 * taskService.setVariableLocal(arg0, arg1, arg2);
		 * 
		 * setVariableLocal 和  setVariable的区别：
		 * setVariable设置流程变量的时候，流程变量名称相同的时候，后一次的值替换前一次的值，
		 * 	而且TASK_ID不存放任务ID的值
		 * setVariableLocal：设置流程变量的时候，针对当前活动的节点设置流程变量，如果一个流程中存在2个活动节点，
		 * 对每个活动节点都设置流程变量，及时流程变量的名称相同，后一次的版本的值也不会替换前一次版本的值，他会使用不同的
		 * 任务ID作为标识，存放2个流程变量值，而且恶意看到TASK_ID额度字段会存放任务ID的值；
		 * 
		 * 还有使用setVariableLocal说明流程变量绑定了当前的任务，当流程继续执行时，下个任务获取不到这个流程变量（
		 * 以为正在执行的流程变量中没有这个数据），所有查询正在执行的任务时不能查询到我们需要的数据，此时需要查询历史的流程变量
		 */
		
		//获取流程变量用get
		runtimeService.getVariable("执行对象ID", "变量名称");
		runtimeService.getVariables("执行对象ID");//返回map参数集合
		//runtimeService.getVariables("执行对象ID", list)//指定参数集合
		
		return "";
	}
	
	/**
	 * 完成我的任务
	 * @return
	 */
	@RequestMapping("completeTask")
	public String completeTask(){
		
		String taskId = "17502";
		
		processEngine.getTaskService().complete(taskId);
		
		return "完成任务" + taskId;
	}
	
	/**
	 * 查询历史流程变量
	 * @return
	 */
	@GetMapping("findHistoryVariables")
	public String findHistoryVariables(){
		
		List<HistoricVariableInstance> list = processEngine.getHistoryService()
				.createHistoricVariableInstanceQuery()
				.variableName("请假原因")
				.list();
		
		System.out.println(list.size());
		
		return "success";
		
	}
	
}
